package utils

import (
	"crypto/rand"
	"encoding/base64"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"goadmin/models"
	"gorm.io/gorm"
	"time"
)

// 时间戳转换成日期
func UnixToTime(timestamp int) string {
	t := time.Unix(int64(timestamp), 0)
	return t.Format("2006-01-02 15:04:05")
}

// 日期转换成时间戳 2020-05-02 15:04:05
func DateToUnix(str string) int64 {
	template := "2006-01-02 15:04:05"
	t, err := time.ParseInLocation(template, str, time.Local)
	if err != nil {
		return 0
	}
	return t.Unix()
}

// 获取时间戳
func GetUnix() int64 {
	return time.Now().Unix()
}

// 获取当前的日期
func GetDate() string {
	template := "2006-01-02 15:04:05"
	return time.Now().Format(template)
}

// 获取年月日
func GetDay() string {
	template := "20060102"
	return time.Now().Format(template)
}

// ConvertMenuListToTree 将扁平菜单列表转换为树形结构
// menus: 所有菜单的切片
// ParentID: 顶级菜单的父ID（通常为0）
func ConvertMenuListToTree(menus []models.Menus, ParentID int) []gin.H {
	var tree []gin.H
	// 遍历所有菜单，找出parentID匹配的菜单
	for _, menu := range menus {
		if menu.ParentID == ParentID {
			// 递归构建子树
			children := ConvertMenuListToTree(menus, menu.ID)
			// 创建当前节点
			node := gin.H{
				"id":          menu.ID,
				"menu_name":   menu.MenuName,
				"router_path": menu.RouterPath,
				"router_icon": menu.RouterIcon,
				"sort":        menu.Sort,
				"components":  menu.Components,
				"parent_id":   menu.ParentID,
			}
			node["children"] = children // 如果有子菜单，添加children字段
			tree = append(tree, node)
		}
	}
	return tree
}

var jwtSecret = []byte("your-secret-key") // 替换为你自己的密钥

type Claims struct {
	UserID   uint   `json:"user_id"`
	Username string `json:"username"`
	jwt.StandardClaims
}

// GenerateToken 生成JWT token
func GenerateToken(userID uint, username string) (string, error) {
	nowTime := time.Now()
	expireTime := nowTime.Add(24 * time.Hour) // 过期时间24小时
	claims := Claims{
		UserID:   userID,
		Username: username,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expireTime.Unix(),
			Issuer:    "your-app-name",
		},
	}
	tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	token, err := tokenClaims.SignedString(jwtSecret)
	return token, err
}

// ParseToken 解析JWT token
func ParseToken(token string) (*Claims, error) {
	tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
		return jwtSecret, nil
	})
	if tokenClaims != nil {
		if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
			return claims, nil
		}
	}

	return nil, err
}

// 分页配置
func Paginate(page, pageSize int) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if page <= 0 {
			page = 1
		}
		switch {
		case pageSize > 100:
			pageSize = 100
		case pageSize <= 0:
			pageSize = 10
		}
		offset := (page - 1) * pageSize
		return db.Offset(offset).Limit(pageSize)
	}
}
func RandomString(length int) string {
	// 计算需要的随机字节数
	// base64编码每4个字符对应3个字节，为确保长度足够，向上取整
	bufferSize := (length*3 + 3) / 4
	buffer := make([]byte, bufferSize)

	// 读取随机字节
	_, err := rand.Read(buffer)
	if err != nil {
		return ""
	}

	// 使用URLEncoding避免特殊字符，并且去掉填充的等号
	randomStr := base64.URLEncoding.EncodeToString(buffer)
	// 截取到指定长度
	return randomStr[:length]
}
func RandomStringWithTime(length int) string {
	if length <= 16 {
		return RandomString(length)
	}
	date := time.Now().Format("20060102150405")
	need := length - len(date)
	if need <= 0 {
		return date[:length]
	}
	return date + RandomString(need)
}
